package com.longrise.android.byjk.plugins.dealsituation.course.video2.education.webvideoedu;

import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import com.longrise.android.byjk.R;
import com.longrise.common.base.BaseActivity;
import com.longrise.android.byjk.plugins.dealsituation.course.video2.dialog.CurrencyDialog;
import com.longrise.android.byjk.plugins.dealsituation.course.video2.dialog.UploadDialog;
import com.longrise.android.byjk.plugins.dealsituation.course.video2.media.IjkVideoView;
import com.longrise.android.byjk.plugins.dealsituation.course.video2.params.VideoConsts;
import com.longrise.android.byjk.plugins.dealsituation.course.video2.params.VideoParams;
import com.longrise.common.utils.AppUtil;
import com.longrise.common.utils.PrintLog;
import com.longrise.android.byjk.widget.view.BaseFrameView;

import java.util.Formatter;
import java.util.Locale;

import tv.danmaku.ijk.media.player.IMediaPlayer;

/**
 * Created by godliness on 2017/8/1.
 * 继续教育之web+video课件学习方式
 */

public class WebVideoEduActivity extends BaseActivity<WebVideoEduPresenter> implements WebVideoView, BaseFrameView.ReloadListener, View.OnClickListener, View.OnTouchListener, IMediaPlayer.OnPreparedListener, IMediaPlayer.OnCompletionListener, IMediaPlayer.OnInfoListener, IMediaPlayer.OnErrorListener {

    private static final String TAG = "WebVideoEduActivity";

    private final int mDefaultTimeOut = 3000;

    private final int UPDATE_PROGRESS_MSG = 0;
    private final int HIDE_MSG = 1;

    private WebView mWebView;
    private WebSettings mWebSettings;

    private BaseFrameView mBaseFrameView;

    private VideoParams mParams;

    private boolean mWebLoadError;
    private boolean mHandPause;
    private boolean mPauseBeforeState;
    private boolean mPrepared;

    /**
     * 播放器布局
     */
    private View mControllerLayout;
    private View mTitleLayout;
    private RelativeLayout mBack;
    private TextView mTvTitle;

    /**
     * 控制栏
     */
    private ImageButton mBtnPause;
    private TextView mTvPosition;
    private TextView mTvDuration;
    private SeekBar mProgress;
    private boolean mDrag;

    /**
     * 缓冲或者出错
     */
    private View mHaze;
    private ProgressBar mPbLoading;
    private TextView mTvError;

    private IjkVideoView mPlayer;
    private int mPosition;

    private StringBuilder mFormatBuilder;
    private Formatter mFormatter;
    private boolean mShow = true;

    private long mNewposition;
    private CurrencyDialog mCurrencyDialog;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case HIDE_MSG:
                    hide();
                    break;

                case UPDATE_PROGRESS_MSG:
                    int pos = setProgress();
                    if (mShow && mPlayer.isPlaying()) {
                        msg = obtainMessage(UPDATE_PROGRESS_MSG);
                        sendMessageDelayed(msg, 1000 - (pos % 1000));
                    }

                default:
                    break;
            }
        }
    };

    @Override
    public int getContentViewId(@Nullable Bundle savedInstanceState) {
        if (savedInstanceState == null) {
            getExtraData();
        } else {
            onRestoreState(savedInstanceState);
        }
        return R.layout.activity_webvideoedu;
    }


    @Override
    public void initView() {
        initVideo();
        mBaseFrameView = (BaseFrameView) findViewById(R.id.bfv_webvideo);
        mBaseFrameView.setOnReloadListener(this);
        mWebView = (WebView) findViewById(R.id.wv_webvideo);
        initWebSetting();

        mPresenter.reLoad();
    }

    private void initVideo() {
        mPlayer = (IjkVideoView) findViewById(R.id.pv_video);
        autoSize(mPlayer);
        mControllerLayout = findViewById(R.id.video_controller_layout);
        mTitleLayout = findViewById(R.id.video_title_layout);

        //title栏
        mBack = (RelativeLayout) findViewById(R.id.rl_back_left);
        mTvTitle = (TextView) findViewById(R.id.tv_title);

        //controller 栏
        mBtnPause = (ImageButton) findViewById(R.id.btn_pause);
        mTvPosition = (TextView) findViewById(R.id.tv_position);
        mTvDuration = (TextView) findViewById(R.id.tv_duration);
        mProgress = (SeekBar) findViewById(R.id.sb_progress);

        mHaze = findViewById(R.id.video_haze);
        mPbLoading = (ProgressBar) findViewById(R.id.pb_loading);
        mTvError = (TextView) findViewById(R.id.tv_showerror);

        regEvent(true);
        openMedia(true);

        mFormatBuilder = new StringBuilder();
        mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());
    }

    private void autoSize(IjkVideoView view) {
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) view.getLayoutParams();
        int windowWidth = AppUtil.getScreenWidth();
        //设置为宽度的一半
        int viewHeight = (windowWidth / 2);
        lp.height = viewHeight;
        view.requestLayout();
    }

    private void fullSize(IjkVideoView view) {
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) view.getLayoutParams();
        lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
        view.requestLayout();
    }

    /**
     * 加载video资源
     */
    private void startPlayer(String url) {
        PrintLog.e(TAG, "url: " + url);
//        buffering(true);
        if (mPlayer != null && !strIsEmpty(url)) {
            mPlayer.setVideoPath(url);
        }
    }

    private void openMedia(boolean isClick) {
        if (mPlayer == null) {
            return;
        }
        mPlayer.setOnPreparedListener(isClick ? this : null);
        mPlayer.setOnCompletionListener(isClick ? this : null);
        mPlayer.setOnErrorListener(isClick ? this : null);
        mPlayer.setOnInfoListener(isClick ? this : null);
    }

    private void regEvent(boolean isClick) {
        if (mBtnPause != null) {
            mBtnPause.setOnClickListener(isClick ? this : null);
        }
        if (mBack != null) {
            mBack.setOnClickListener(isClick ? this : null);
        }
        if (mTvError != null) {
            mTvError.setOnClickListener(isClick ? this : null);
        }
        if (mProgress != null) {
            mProgress.setOnTouchListener(isClick ? this : null);
            mProgress.setOnSeekBarChangeListener(isClick ? mSeekListener : null);
            mProgress.setMax(1000);
        }
        if (mControllerLayout != null) {
            mControllerLayout.setOnClickListener(isClick ? this : null);
        }
        if (mTitleLayout != null) {
            mTitleLayout.setOnClickListener(isClick ? this : null);
        }
        if (mPlayer != null) {
            mPlayer.setOnTouchListener(isClick ? this : null);
        }
    }

    private SeekBar.OnSeekBarChangeListener mSeekListener = new SeekBar.OnSeekBarChangeListener() {
        public void onStartTrackingTouch(SeekBar bar) {
            show(3600000);

            mHandler.removeMessages(UPDATE_PROGRESS_MSG);
        }

        public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) {
            if (!fromuser) {
                return;
            }

            long duration = mPlayer.getDuration();
            mNewposition = (duration * progress) / 1000L;
            if (mTvPosition != null) {
                mTvPosition.setText(stringForTime((int) mNewposition));
            }
        }

        public void onStopTrackingTouch(SeekBar bar) {
            mPlayer.seekTo((int) mNewposition);
            setProgress();
            updatePausePlay();
            show(mDefaultTimeOut);

            mHandler.sendEmptyMessage(UPDATE_PROGRESS_MSG);
        }
    };

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_pause:
                doPausePlay();
                break;

            case R.id.rl_back_left:
                finish();
                break;

            case R.id.tv_showerror:
                toErrorOption();
                break;

            default:
                break;
        }
    }

    /**
     * 播放/暂停
     */
    private void doPausePlay() {
        if (mPlayer == null && mBtnPause != null) {
            return;
        }
        if (mPlayer.isPlaying()) {
            mPlayer.pause();
            mHandPause = true;
            mBtnPause.setBackground(getResources().getDrawable(android.R.drawable.ic_media_play));
        } else {
            mPlayer.start();
            mHandPause = false;
            mBtnPause.setBackground(getResources().getDrawable(android.R.drawable.ic_media_pause));
        }
    }

    /**
     * show 控制栏
     */
    private void show(int timeOut) {
        if (!mShow && isAnchor()) {
            setProgress();
            mControllerLayout.setVisibility(View.VISIBLE);
            mTitleLayout.setVisibility(View.VISIBLE);
            mShow = true;
        }
        updatePausePlay();
        mHandler.sendEmptyMessage(UPDATE_PROGRESS_MSG);

        Message msg = mHandler.obtainMessage(HIDE_MSG);
        if (timeOut != 0) {
            mHandler.removeMessages(HIDE_MSG);
            mHandler.sendMessageDelayed(msg, timeOut);
        }
    }

    private void updatePausePlay() {
        if (mBtnPause != null && mPlayer != null) {
            mBtnPause.setBackground(mPlayer.isPlaying() ? getResources().getDrawable(android.R.drawable.ic_media_pause) : getResources().getDrawable(android.R.drawable.ic_media_play));
        }
    }

    /**
     * hide 控制栏
     */
    private void hide() {
        if (mShow && isAnchor()) {
            mControllerLayout.setVisibility(View.GONE);
            mTitleLayout.setVisibility(View.GONE);
            mShow = false;
        }
        mHandler.removeMessages(HIDE_MSG);
        mHandler.removeMessages(UPDATE_PROGRESS_MSG);
    }

    private boolean isAnchor() {
        return mControllerLayout != null && mTitleLayout != null;
    }

    private void buffering(boolean isShowing) {
        if (mPbLoading != null) {
            mPbLoading.setVisibility(isShowing ? View.VISIBLE : View.GONE);
        }
    }

    /**
     * 进度值
     */
    private int setProgress() {
        int position = getCurrentPosition();
        int duration = getDuration();

        if (mProgress != null) {
            if (duration > 0) {
                long pos = 1000L * position / duration;
                mProgress.setProgress((int) pos);
            }
            int percent = mPlayer.getBufferPercentage();
            mProgress.setSecondaryProgress(percent * 10);
        }

        if (mTvDuration != null) {
            mTvDuration.setText(stringForTime(duration));
        }
        if (mTvPosition != null) {
            mTvPosition.setText(stringForTime(position));
        }
        return position;
    }

    /**
     * 毫秒转时分秒
     */
    private String stringForTime(int timeMs) {
        int totalSeconds = timeMs / 1000;

        int seconds = totalSeconds % 60;
        int minutes = (totalSeconds / 60) % 60;
        int hours = totalSeconds / 3600;

        mFormatBuilder.setLength(0);
        if (hours > 0) {
            return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString();
        } else {
            return mFormatter.format("%02d:%02d", minutes, seconds).toString();
        }
    }

    private void initWebSetting() {
        mWebSettings = mWebView.getSettings();
        mWebSettings.setLoadWithOverviewMode(true);
        mWebSettings.setUseWideViewPort(true);
        mWebSettings.setJavaScriptEnabled(true);
        //设置 缓存模式 不用缓存 使用localStorage
        mWebSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
        mWebSettings.setDomStorageEnabled(true);
        mWebSettings.setAppCacheMaxSize(1024 * 1024 * 8);
        String absolutePath = getApplicationContext().getCacheDir().getAbsolutePath();
        mWebSettings.setAppCachePath(absolutePath);
        mWebSettings.setAllowFileAccess(true);
        mWebSettings.setAppCacheEnabled(true);
        mWebSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);
        mWebView.setWebChromeClient(mWebChromeClient);
        mWebView.setWebViewClient(mWebViewClient);
    }

    private WebChromeClient mWebChromeClient = new WebChromeClient() {

        @Override
        public void onReceivedTitle(WebView view, String title) {
            super.onReceivedTitle(view, title);
        }

        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);
        }
    };

    private WebViewClient mWebViewClient = new WebViewClient() {

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            if (mWebLoadError) {
                error();
            } else {
                mWebLoadError = false;
                dismissLoadingDialog();
            }
        }

        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
            super.onReceivedError(view, request, error);
            mWebLoadError = true;
        }
    };

    @Override
    public void onReload(View v) {
        String webPath = mPresenter.webPath();
        if (!strIsEmpty(webPath)) {
            loadWeb(webPath);
        } else {
            mPresenter.reLoad();
        }
    }

    private void getExtraData() {
        Intent extraIntent = getIntent();
        mParams = extraIntent.getParcelableExtra(VideoConsts.VIDEO_PARAMS_PARCELABLE);
    }

    @Override
    public void setTitle() {
        if (mParams != null && mTvTitle != null) {
            boolean hasqa = mParams.mHasqa;
            mTvTitle.setText(mParams.mCwidName + (hasqa ? "（课后习题）" : ""));
        }
    }

    @Override
    public void dismissLoadingDialog() {
        mBaseFrameView.post(new Runnable() {
            @Override
            public void run() {
                loadFinishStatus();
            }
        });
    }

    @Override
    public void showLoadingDialog() {
        mBaseFrameView.post(new Runnable() {
            @Override
            public void run() {
                loadStartStatus();
            }
        });
    }

    @Override
    public void error() {
        mBaseFrameView.post(new Runnable() {
            @Override
            public void run() {
                loadErrorStatus();
            }
        });
    }

    @Override
    public VideoParams getVideoParams() {
        return mParams;
    }

    @Override
    public void parse(String videopath, String webpath, int position, boolean videopass) {
        if (isFinishing()) {
            return;
        }
        this.mPosition = position;
        setSeekBarDrag(videopass);
        startPlayer(videopath);
        loadWeb(webpath);
    }

    /**
     * 加载web地址
     */
    private void loadWeb(String url) {
        PrintLog.e(TAG, "url: " + url);
        if (!strIsEmpty(url)) {
            mWebView.loadUrl(url);
        } else {
            dismissLoadingDialog();
            setWebImageView();
        }
    }

    private boolean strIsEmpty(String str) {
        return TextUtils.isEmpty(str);
    }

    @Override
    public int getCurrentPosition() {
        return mPlayer == null ? 0 : mPlayer.getCurrentPosition();
    }

    @Override
    public int getDuration() {
        return mPlayer == null ? -1 : mPlayer.getDuration();
    }

    @Override
    public void onBack() {
        finish();
    }

    @Override
    public void setDrag(boolean isDialog) {
        //不在拦截seekbar的onTouchEvent()
        mDrag = false;
        if (isDialog && !isFinishing()) {
            createAdoptDialog();
        }
    }

    @Override
    public boolean actFinished() {
        return isFinishing();
    }

    @Override
    public void setScreenOrientation(int orientation) {

    }

    public void setSeekBarDrag(boolean drag) {
        mDrag = drag;
    }

    public void setWebImageView() {
        if (mWebView != null) {
            mWebView.setVisibility(View.GONE);
        }
        ImageView iv = (ImageView) findViewById(R.id.iv_hint);
        iv.setImageDrawable(getResources().getDrawable(R.drawable.bg_error_3));
        iv.setVisibility(View.VISIBLE);
    }

    private void loadStartStatus() {
        mBaseFrameView.setLoadingStatus(BaseFrameView.LoadingStatus.LOADING);
        mBaseFrameView.setVisibility(View.VISIBLE);
    }

    private void loadFinishStatus() {
        mBaseFrameView.setLoadingStatus(BaseFrameView.LoadingStatus.SUCCESS);
        mBaseFrameView.setVisibility(View.GONE);
    }

    private void loadErrorStatus() {
        mBaseFrameView.setLoadingStatus(BaseFrameView.LoadingStatus.ERROR);
        mBaseFrameView.setVisibility(View.VISIBLE);
    }

    @Override
    protected void onResume() {
        super.onResume();
        doResume();
    }

    private void doResume() {
        if (mPlayer != null && mPauseBeforeState) {
            mPlayer.start();
        }
        if (mPrepared) {
            mPresenter.startDefendStudy();
        }
        if (!mPlayer.isPlaying() && mPrepared) {
            show(mDefaultTimeOut);
        }
    }

    private void doPause() {
        if (mPlayer != null) {
            mPauseBeforeState = mPlayer.isPlaying();
            mPosition = getCurrentPosition();
            mPlayer.pause();
        }
    }

    private void createAdoptDialog() {
        dismissAdoptDialog();
        mCurrencyDialog = new CurrencyDialog(this);
        mCurrencyDialog.show();
    }

    private void dismissAdoptDialog() {
        if (mCurrencyDialog != null && mCurrencyDialog.isShowing()) {
            mCurrencyDialog.dismiss();
            mCurrencyDialog = null;
        }
    }

    @Override
    protected void onPause() {
        doPause();
        super.onPause();
    }

    @Override
    protected void onStop() {
        super.onStop();
        hide();
        mPresenter.stopDefendStudy();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable(VideoConsts.VIDEO_PARAMS_PARCELABLE, mParams);
    }

    private void onRestoreState(Bundle state) {
        if (state != null) {
            mParams = state.getParcelable(VideoConsts.VIDEO_PARAMS_PARCELABLE);
        }
    }

    @Override
    public void onPrepared(IMediaPlayer iMediaPlayer) {
        if (isFinishing()) {
            return;
        }
        if (mPlayer == null) {
            return;
        }
        mPrepared = true;
        mPlayer.seekTo(mPosition);
        mPlayer.start();
        mPresenter.monitorDefendStudy(getDuration());
        buffering(false);
        show(mDefaultTimeOut);
    }

    @Override
    public void onCompletion(IMediaPlayer iMediaPlayer) {
        PrintLog.e(TAG, "onCompletion");
        if (mPresenter != null) {
            mPresenter.stopDefendStudy();
            mPresenter.exerciseOptions();
        }
        if (!mPresenter.isVideopass()) {
            mPresenter.grenatorUploadDialog(UploadDialog.DIALOG_TYPE_ONE);
        }
    }

    @Override
    public boolean onError(IMediaPlayer iMediaPlayer, int what, int extra) {
        buffering(false);
        overshadow();
        return true;
    }

    private void overshadow() {
        hide();
        mPlayer.setOnTouchListener(null);
        showError(true);
        if (mHaze != null) {
            mHaze.setBackground(getResources().getDrawable(R.drawable.shape_video_background_shadow));
        }
    }

    private void transparent() {
        if (mHaze != null) {
            Drawable videoDrawable = getResources().getDrawable(R.drawable.shape_video_background_transparent);
            mHaze.setBackground(videoDrawable);
        }
        showError(false);
        mPlayer.setOnTouchListener(this);
    }

    private void showError(boolean isError) {
        if (mTvError != null) {
            mTvError.setVisibility(isError ? View.VISIBLE : View.GONE);
        }
    }

    private void toErrorOption() {
        if (!checkNetWorkEnable()) {
            return;
        }
        String videoPath = mPresenter.videoPath();
        if (!strIsEmpty(videoPath)) {
            startPlayer(videoPath);
        } else {
            mPresenter.reLoad();
        }
        transparent();
    }

    @Override
    public boolean onInfo(IMediaPlayer iMediaPlayer, int what, int extra) {
        switch (what) {
            case MediaPlayer.MEDIA_INFO_BUFFERING_START:
                buffering(true);
                break;

            case MediaPlayer.MEDIA_INFO_BUFFERING_END:
                if (mPlayer.isPlaying() || mHandPause) {
                    buffering(false);
                }
                break;

            default:
                buffering(false);
                break;
        }
        return true;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (v.getId() == R.id.sb_progress) {
            if (mDrag) {
                showToast(getString(R.string.dont_drivri));
            }
            return mDrag;
        } else if (v.getId() == R.id.pv_video) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    if (mShow) {
                        hide();
                    } else {
                        show(mDefaultTimeOut);
                    }
                    break;

                default:
                    break;
            }
        }
        return false;
    }

    private void release() {
        if (mPlayer != null) {
            mPlayer.stopPlayback();
        }
        detachWebView();
        openMedia(false);
        regEvent(false);
        mHandler = null;
        mSeekListener = null;
        mWebChromeClient = null;
        mWebViewClient = null;
    }

    private void detachWebView() {
        if (mWebView != null) {
            ViewParent viewParent = mWebView.getParent();
            if (viewParent != null) {
                ((ViewGroup) viewParent).removeView(mWebView);
            }
            mWebView.removeAllViews();
            mWebView.destroy();
            mWebSettings.setJavaScriptEnabled(false);
        }
    }

    private void sendMessage() {
        mPresenter.toRefrushCourseDetail();
    }

    @Override
    protected void onDestroy() {
        release();
        sendMessage();
        super.onDestroy();
    }
}
